package com.example.webcrawler.controller;

import com.example.webcrawler.model.ApiRequest;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.annotation.PostConstruct;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Pattern;

@Component
@EnableWebSocket
public class FlowTestController extends TextWebSocketHandler implements WebSocketConfigurer {

    private static final Logger logger = LoggerFactory.getLogger(FlowTestController.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();

    // 存储所有活跃的WebSocket会话
    private final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>();

    // 拦截规则
    private volatile boolean interceptEnabled = false;
    private volatile String interceptPattern = "";
    private volatile Pattern compiledPattern = null;

    @PostConstruct
    public void init() {
        logger.info("FlowTestController initialized");
    }

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(this, "/ws/monitor").setAllowedOrigins("*");
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.add(session);
        logger.info("WebSocket connection established: {}", session.getId());
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        try {
            // 解析客户端发送的消息
            String payload = message.getPayload();
            logger.debug("Received message: {}", payload);

            // 解析JSON消息
            JsonNode jsonNode = objectMapper.readTree(payload);
            String type = jsonNode.get("type").asText();

            switch (type) {
                case "start":
                    // 启动监控
                    String url = jsonNode.get("url").asText();
                    logger.info("Starting monitoring for URL: {}", url);
                    // 这里可以启动实际的监控逻辑
                    break;

                case "setInterceptRules":
                    // 设置拦截规则
                    boolean enabled = jsonNode.get("enabled").asBoolean();
                    String pattern = jsonNode.has("pattern") ? jsonNode.get("pattern").asText() : "";
                    setInterceptRules(enabled, pattern);
                    logger.info("Intercept rules updated - enabled: {}, pattern: {}", enabled, pattern);
                    break;

                default:
                    logger.warn("Unknown message type: {}", type);
            }

        } catch (Exception e) {
            logger.error("Error handling WebSocket message", e);
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session);
        logger.info("WebSocket connection closed: {} with status: {}", session.getId(), status);
    }

    /**
     * 向所有连接的客户端广播请求信息
     */
    public void broadcastRequest(ApiRequest request) {
        if (sessions.isEmpty()) {
            return;
        }

        try {
            // 创建要发送的消息
            MessageWrapper wrapper = new MessageWrapper();
            wrapper.setType("request");
            wrapper.setRequest(request);

            String jsonMessage = objectMapper.writeValueAsString(wrapper);
            TextMessage textMessage = new TextMessage(jsonMessage);

            // 向所有会话发送消息
            for (WebSocketSession session : sessions) {
                if (session.isOpen()) {
                    try {
                        session.sendMessage(textMessage);
                    } catch (java.io.IOException e) {
                        logger.warn("Failed to send message to session: {}", session.getId(), e);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("Error broadcasting request", e);
        }
    }

    /**
     * 检查URL是否匹配拦截模式
     */
    public boolean shouldIntercept(String url) {
        if (!interceptEnabled || compiledPattern == null) {
            return false;
        }

        try {
            return compiledPattern.matcher(url).matches();
        } catch (Exception e) {
            logger.warn("Error matching URL against pattern: {}", url, e);
            return false;
        }
    }

    /**
     * 设置拦截规则
     */
    public void setInterceptRules(boolean enabled, String pattern) {
        this.interceptEnabled = enabled;
        this.interceptPattern = pattern;

        if (pattern != null && !pattern.isEmpty()) {
            try {
                // 将简单的通配符模式转换为正则表达式
                String regex = pattern.replace("*", ".*").replace("?", ".");
                this.compiledPattern = Pattern.compile(regex);
            } catch (Exception e) {
                logger.warn("Invalid intercept pattern: {}", pattern, e);
                this.compiledPattern = null;
            }
        } else {
            this.compiledPattern = null;
        }

    }

    /**
     * 消息包装类
     */
    public static class MessageWrapper {
        private String type;
        private ApiRequest request;

        // Getters and setters
        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public ApiRequest getRequest() {
            return request;
        }

        public void setRequest(ApiRequest request) {
            this.request = request;
        }
    }
}
